/*
 */

#include "dht11.h"

#include <stdio.h>
//#include <string.h>
#include <unistd.h>

#include "esp_log.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/gpio.h"
//#include "sdkconfig.h"


#define AHT20_MAX_RETRY 10

#define LED_PIN 12
static const char* TAG = "DHT11";
unsigned long cnt=0;


void pick(int c)
{
    gpio_set_level(LED_PIN,0);
    delay_us(c);
     gpio_set_level(LED_PIN,1);

}
uint32_t DHT11_Config()
{

    return ESP_OK;
}

uint32_t DHT11_GetResult(float* temp, float* humi)
{
    uint8_t buffer[5];
    int ret=0;
    printf("[Dht11 Task]get result count:%lu.\n",cnt++);
//    printf("[DHT11 Task] pin:%d\n",DHT11_DQ_PIN);
    if ((ret = dht11_read_data(buffer)) == 0)
    {
          //printf("[DHT11] state:%d\n",ret);
         *humi = buffer[0] + buffer[1] / 10.0;
         *temp = buffer[2] + buffer[3] / 10.0;

         return ESP_OK;
    }
    printf("[DHT11] read error:%d.\n",ret);
//    printf("loop %lu\n",(1000*(SYSCLK)-(B))/A);
/*        dht11_gpio_output();

		for(int i=0;i<10;i++){
			DHT11_OUT_H;
			delay_us(1000);
			DHT11_OUT_L;
			delay_us(1000);
        }
  */     
//       return WIFI_IOT_ERR_DHT11_READ_ERROR;
    return ret ;
}


static __inline void delay_clock(int ts)
{
	uint32_t start, curr;

	__asm__ __volatile__("rsr %0, ccount" : "=r"(start));
	do
		__asm__ __volatile__("rsr %0, ccount" : "=r"(curr));
	while (curr - start <= ts);
}

void delay_us(uint32_t cnt)
{
	usleep(cnt);
//
	//delay_clock(240);//1us	
}

void	dht11_gpio_init(void)
{
	gpio_set_direction(DHT11_DQ_PIN,GPIO_MODE_OUTPUT);
//	gpio_set_pull_mode(DHT11_DQ_PIN,GPIO_PULLUP_ONLY);
	gpio_set_level(DHT11_DQ_PIN,1);
   	//gpio_set_direction(LED_PIN,GPIO_MODE_OUTPUT);

}
void dht11_gpio_input(void)
{
	gpio_set_direction(DHT11_DQ_PIN,GPIO_MODE_INPUT);	
//	gpio_set_pull_mode(DHT11_DQ_PIN,GPIO_PULLUP_ONLY);
}

void dht11_gpio_output(void)
{
	gpio_set_direction(DHT11_DQ_PIN,GPIO_MODE_OUTPUT);
//	gpio_set_pull_mode(DHT11_DQ_PIN,GPIO_PULLUP_ONLY);
}

uint8_t dht11_gpio_read(void)
{	
	return gpio_get_level(DHT11_DQ_PIN);
}
int  dht11_reset(void)
{
    // 按照DHT11手册步骤
    //gpio_set_level(LED_PIN,0);
    dht11_gpio_output();
    DHT11_OUT_L;
    delay_us(19000);
    DHT11_OUT_H;
    dht11_gpio_input();
    delay_us(30);
    //waiting dht11 pulldown.
    //gpio_set_level(LED_PIN,1);


    u8 flag=2;
    //check dht 83s low leve reply.
    if( !DHT11_IN )
    {
         //waiting for high leve
        while(!DHT11_IN && flag++)
                delay_us(10);
        flag = 2;
        //check 87us high leve replay.
        while(DHT11_IN && flag++)
                delay_us(10);
        return 0; 
    }
    //pick(1);
    return 1 ;
}

u16 dht11_scan(void)
{
    return DHT11_IN;
}


u8 dht11_read_byte(void)
{
    u8 i;
    u8 data = 0;
    for (i = 0; i < 8; i++)
    {
        u8 flag =2;
        //waiting bit 54us low level.
        while((DHT11_IN == RESET) && flag++)
                delay_us(10);
        delay_us(35);
        u8 temp=0;
        if(DHT11_IN == SET)
                temp=1;

        flag = 2;
        while((DHT11_IN == SET) && flag++)
                delay_us(10);
        if(flag == 1)
                break;

        data <<= 1;
        data |=temp;
    }
    return data;
}

u16 dht11_read_data(uint8_t buffer[5])
{
    u16 i = 0;
    //printf("read from dht11.\n");
    dht11_gpio_init();
    if( dht11_reset())
    {
        printf("dht11 reset error.\n");
        return 1;
    }
//        pick(3);
        //printf("[DHT11] ready to read byte.\n");
        for (i = 0; i < 5; i++)
        {
            buffer[i] = dht11_read_byte();
        }

        while (dht11_scan() == RESET)
                delay_us(10);
        dht11_gpio_output();
        DHT11_OUT_H;

        uint8_t checksum = buffer[0] + buffer[1] + buffer[2] + buffer[3];

        if(0)
        {
            for(i=0;i<5;i++){
                printf("[%02x]",buffer[i]);
        
            }
            printf("\n");
        }
        if (checksum != buffer[4])
        {
            // checksum error
            return 2;
        }

    return 0;
}

